/**
 * 
 */
package com.ng.framework.persistence;

import java.io.Serializable;
import java.text.ParseException;
import java.util.Date;

import com.ng.framework.util.NGUtil;

public class NGSearchParameter implements Serializable {

	private static final long serialVersionUID = 1022363473227460047L;

	public enum Type {
		STRING(), INTEGER(), DATE();

	}

	public enum UnaryOperation {
		GREATER_THAN(), SMALLER_THAN(), EQUALS(), LIKE(), NOT_EQUALS()
	}

	public enum BinaryOperation {
		AND(), OR()
	}

	private Class clazz;

	private String attribute;

	private String expectedValue;

	private Type type;

	private UnaryOperation unaryOperation;

	private BinaryOperation binaryOperation;

	private NGSearchParameter parameterA;

	private NGSearchParameter parameterB;

	private String joinAttribute;

	private boolean join;

	public NGSearchParameter(final Class clazz, final String attribute,
			final String expectedValue, final Type type,
			final UnaryOperation operation) {
		super();
		this.clazz = clazz;
		this.attribute = attribute;
		this.expectedValue = expectedValue;
		this.type = type;
		this.unaryOperation = operation;
	}

	public NGSearchParameter(final Class clazz, final String attribute,
			final String expectedValue, final Type type,
			final UnaryOperation operation, boolean join, String joinAttribute) {
		super();
		this.clazz = clazz;
		this.attribute = attribute;
		this.expectedValue = expectedValue;
		this.type = type;
		this.unaryOperation = operation;
		this.join = join;
		this.joinAttribute = joinAttribute;
	}

	public NGSearchParameter(final NGSearchParameter parameterA,
			final NGSearchParameter parameterB,
			final BinaryOperation binaryOperation) {
		this.parameterA = parameterA;
		this.parameterB = parameterB;
		this.binaryOperation = binaryOperation;
	}

	public String getCustomFromHQL() {
		StringBuilder customFromHQL = new StringBuilder();
		if (join) {
			customFromHQL.append("IN (");
			customFromHQL.append(this.clazz.getSimpleName());
			customFromHQL.append(".");
			customFromHQL.append(attribute);
			customFromHQL.append(") ");
			customFromHQL.append(" as ");
			customFromHQL.append(attribute);

			return customFromHQL.toString();
		}
		return "";
	}
	public String getCustomWhereHQL() {
		final StringBuilder customWhereHQL = new StringBuilder();
		if (this.unaryOperation != null) {

			if (join) {

				customWhereHQL.append(this.attribute);
				customWhereHQL.append(".");
				customWhereHQL.append(this.joinAttribute);
			} else {
				customWhereHQL.append(this.clazz.getSimpleName());
				customWhereHQL.append(".");
				customWhereHQL.append(this.attribute);
			}
			switch (this.unaryOperation) {
				case EQUALS :

					if (this.type.equals(Type.INTEGER)) {
						customWhereHQL.append("=");
						customWhereHQL.append(this.expectedValue);
					} else {
						customWhereHQL.append("='");
						customWhereHQL.append(this.expectedValue);
						customWhereHQL.append("'");
					}
					break;
				case NOT_EQUALS :

					if (this.type.equals(Type.INTEGER)) {
						customWhereHQL.append("<>");
						customWhereHQL.append(this.expectedValue);
					} else {
						customWhereHQL.append("<>'");
						customWhereHQL.append(this.expectedValue);
						customWhereHQL.append("'");
					}
					break;
				case GREATER_THAN :
					if (this.type.equals(Type.DATE)) {
						try {
							final Date oldFormat = NGUtil.ddMMyyyy_dateFormat
									.parse(this.expectedValue);
							customWhereHQL.append(" >= '");
							customWhereHQL
									.append(NGUtil.yyyyMMdd_HHmmss_dateFormat
											.format(oldFormat));
							customWhereHQL.append("'");
						} catch (final ParseException e) {
							e.printStackTrace();
						}
					} else {
						customWhereHQL.append(" >= '");
						customWhereHQL.append(this.expectedValue);
						customWhereHQL.append("'");
					}
					break;
				case SMALLER_THAN :
					if (this.type.equals(Type.DATE)) {
						try {
							final Date oldFormat = NGUtil.ddMMyyyy_dateFormat
									.parse(this.expectedValue);
							customWhereHQL.append(" <= '");
							customWhereHQL
									.append(NGUtil.yyyyMMdd_HHmmss_dateFormat
											.format(oldFormat));
							customWhereHQL.append("'");
						} catch (final ParseException e) {
							e.printStackTrace();
						}
					} else {
						customWhereHQL.append(" <= '");
						customWhereHQL.append(this.expectedValue);
						customWhereHQL.append("'");
					}
					break;
				case LIKE :
					customWhereHQL.append(" LIKE '%");
					customWhereHQL.append(this.expectedValue);
					customWhereHQL.append("%'");
				default :
					break;
			}
		} else {
			customWhereHQL.append("(");
			customWhereHQL.append(this.parameterA.getCustomWhereHQL());
			if (this.binaryOperation.equals(BinaryOperation.AND)) {
				customWhereHQL.append(" AND ");
			} else if (this.binaryOperation.equals(BinaryOperation.OR)) {
				customWhereHQL.append(" OR ");
			}
			customWhereHQL.append(this.parameterB.getCustomWhereHQL());
			customWhereHQL.append(")");
		}
		return customWhereHQL.toString();

	}
}
